from datetime import datetime, date
from typing import TypeVar, Generic, Optional, Annotated

from pydantic import BaseModel, Field, BeforeValidator, PlainSerializer

from src.utils.common_utils import to_int, to_str, to_datetime, to_date

"""
定义一个泛型作为返回结果类型
"""
T = TypeVar('T')


# 通用结果返回
class Rest(BaseModel, Generic[T]):
    """
    通用响应模型类，继承自BaseModel并支持泛型
    参数:
        code: 响应状态码，整数类型
        msg: 响应消息，字符串类型
        data: 响应数据，可选类型，默认为None
    """
    code: int = Field(default=200, description='响应状态码')
    msg: str = Field(default='请求成功！！', description='响应消息')
    data: Optional[T] = Field(default=None, description='响应数据')

    @classmethod
    def ok(cls, data=None, msg='请求成功！！', code=200) -> 'Rest[T]':
        return Rest(code=code, msg=msg, data=data)

    @classmethod
    def fail(cls, data=None, msg='请求失败！！', code=500) -> 'Rest[T]':
        return Rest(code=code, msg=msg, data=data)


class PageResult(BaseModel, Generic[T]):
    """
    分页结果模型类
    参数:
        current: 当前页码，整数类型
        size: 每页记录数，整数类型
        total: 总记录数，整数类型
        data: 响应数据，可选类型，默认为None
    """
    data: Optional[list[T]] = Field(default=[], description='响应数据')
    total: int = Field(default=0, description='总记录数')
    current: int = Field(default=1, description='当前页码')
    pageSize: int = Field(default=10, description='每页记录数')


class PageParam(BaseModel):
    """
    分页参数模型类
    参数:
        current: 当前页码，整数类型
        size: 每页记录数，整数类型
        sorter: 排序字段，字符串类型
    """
    current: int = Field(default=1, description='当前页码')
    pageSize: int = Field(default=10, description='每页记录数')
    sorter: str = Field(default=None, description='排序字段.例如：id desc,name asc')


"""
处理 bigint 类型在前端精度丢失的问题（bigint 序列化与反序列化问题）

"""
# 定义 BigInt 类型：输入自动转 int，输出自动转 str
Bigint = Annotated[
    Optional[int],
    BeforeValidator(to_int),  # 反序列化：str -> int
    PlainSerializer(to_str, return_type=str),  # 序列化：int -> str
    Field(json_schema_extra={'format': 'bigint-string'})  # 添加OpenAPI扩展
]
"""
处理 datetime 类型序列化与反序列化问题

"""
# 定义 Datetime 类型：输入自动转 datetime，输出自动转 str
Datetime = Annotated[
    Optional[datetime],
    BeforeValidator(to_datetime),  # 反序列化：str -> int
    PlainSerializer(to_str, return_type=str),  # 序列化：int -> str
    Field(json_schema_extra={'format': 'datetime-string'})  # 添加OpenAPI扩展
]

"""
处理 date 类型序列化与反序列化问题

"""
# 定义 Date 类型：输入自动转 datetime，输出自动转 str
Date = Annotated[
    Optional[date],
    BeforeValidator(to_date),  # 反序列化：str -> int
    PlainSerializer(to_str, return_type=str),  # 序列化：int -> str
    Field(json_schema_extra={'format': 'date-string'})  # 添加OpenAPI扩展
]
